package com.nulldev.util.web.nCaptcha.backend.user;

import com.nulldev.util.crypto.encryptAPI.manage.EncryptAPI;
import com.nulldev.util.crypto.passwords.PasswordGenerator.PasswordGeneratorBuilder;
import com.nulldev.util.io.MD5Utils;
import com.nulldev.util.math.MathUtil;
import com.nulldev.util.other.ArrayUtils;

public class User {
	private final String ip;
	/**
	 * Level 0 = Low, not a bot. <br>
	 * Level 1 = Medium, seems to be special. <br>
	 * Level 2 = High, something is wrong. <br>
	 * Level 3 = Bot, prevent user captcha for up to an hour. <br>
	 */
	private int _captcha_level = 0;
	private long expiry = (System.currentTimeMillis() + 3600000);
	
	public User(final String ip) {
		this.ip = ip;
	}

	public void captchaFailed() {
		this._captcha_level = MathUtil.clamp(0, 3, this._captcha_level + 1);
	}
	
	public void captchaPassed() {
		this._captcha_level = MathUtil.clamp(0, 3, this._captcha_level - 1);
		this._captcha_finished = true;
	}

	public String getIP() {
		return this.ip;
	}

	public boolean isNotBot() {
		final boolean notBot = this._captcha_level < 3;
		return notBot;
	}

	public int getLevel() {
		return this._captcha_level;
	}

	private String[] expectedResults = new String[0];
	public void setExpectedResults(final String[] result) {
		this.expectedResults = result;
	}
	
	public String[] getExpectedResults() {
		return this.expectedResults;
	}
	
	public boolean validExpectedResult(final String input) {
		if (input == null || input.length() == 0) {
			return false;
		}
		return ArrayUtils.StringArrayUtils.contains(this.expectedResults, input);
	}

	public void resetCaptchaStatus() {
		this._captcha_level = 0;
	}

	private boolean _captcha_finished;
	public boolean isExpired() {
		return System.currentTimeMillis() > this.expiry;
	}
	
	public boolean captchaDone() {
		return this._captcha_finished;
	}

	public String getUID() {
		final String o = MD5Utils.getMD5Hex(this.expectedResults);
		return MD5Utils.getMD5Hex(this.ip + o);
	}

	public long time() {
		return this.expiry - System.currentTimeMillis();
	}
	
	private final String userKey = new PasswordGeneratorBuilder()
										.useDigits(true).useLower(true)
										.usePunctuation(true).useUpper(true)
										.build()
										.generate(32);
	
	public String key() {
		return this.userKey;
	}
	
	public String encryptPayload(final String payload) {
		return EncryptAPI.getEncryptorForEncryption("XXTEA").encrypt(payload, this.userKey);
	}
}
